#ifndef TABLESYM_H
#define TABLESYM_H

#include "Arbre.h"

typedef struct varSym* VARSYM;
typedef struct fctSym* FCTSYM;
typedef struct varSym VARSYMNODE;
typedef struct fctSym FCTSYMNODE;

struct varSym {
    char* name;
    char* type;
    int level;
    int address;//adresse locale (pour mettre sur la pile)
    int varMode;// Si varMode=1 (Var),  varMode=0 (sans Var), varMode=-1 (decl)

    TREE locationOnTree;	
    FCTSYM fct;

    VARSYM next;
    VARSYM prev;
};

struct fctSym {
	char* name;
	char* retType;
	TREE locationOnTree;
	int level;
	int numFct;
   
	
	int isMain; //la fonction est-elle le main ?
   
        int nbArguments;
	int nbVar;
		
	VARSYM nextVar; //variable de déclaration
	

	FCTSYM childFct; //Toutes les fct imbriquées
	FCTSYM parentFct; //Fct englobante 
	FCTSYM next; //fct suivante au même niveau
	FCTSYM prev; //fct precedente au même niveau
};


FCTSYM createSTNodeFct();
/*
	a. Objets utilisés: /
	b. Pré-conditions : /
	c. Post-conditions : un noeud de type fonction (FCTSYM) a été créé.
	d. Description : crée un noeud de type fonction (FCTSYM).
*/

VARSYM createSTNodeVar();
/*
	a. Objets utilisés: /
	b. Pré-conditions : /
	c. Post-conditions : un noeud de type variable (VARSYM) a été créé.
	d. Description : crée un noeud de type variable (VARSYM).
*/

extern FCTSYM createSymTable();
/*
	a. Objet utilisés : /
	b. Pré-conditions : /
	c. Post-conditions : la table des symboles a été créée.
	d. Description : crée le premier nœud FCTSYM de la table des symboles.
*/

extern void freeSymTableFct(FCTSYM fctSym);
/*
	a. Objets utilisés :
		i. FCTSYM fctSym : le pointeur de fonction à libérer.
	b. Pré-conditions : /.
	c. Post-conditions : l’espace mémoire occupé pour la table des symboles a été libéré.
	d. Description : libère l’espace mémoire occupé par la table des symboles.
*/
extern void freeSymTableVar(VARSYM varSym);
/*
	a. Objets utilisés :
		i. VARSYM varSym : le pointeur de variable à libérer.
	b. Pré-conditions : /.
	c. Post-conditions : l’espace mémoire occupé par les variables d’une fonction a été libéré.
	d. Description : libère l’espace mémoire occupé par les variables d’une fonction de la table des symboles.
*/

extern void fillSymTableWithFonction(FCTSYM lastFct, TREE tree, int level, char* nameMain);
/*

	a. Objets utilisés:
		i. FCTSYM lastAddedFct: la dernière fonction à avoir été ajoutée à la table des symboles.
		ii.TREE tree : le nœud de l’arbre correspondant à la fonction à ajouter.
		iii.Int level : le niveau d’imbrication de la fonction.
		iv.Char *nameMain : le nom de la fonction main.
	b. Pré-conditions : le nœud racine de la table des symboles a été créé.
	c. Post-conditions : les fonctions ont été ajoutées à la table des symboles.
	d. Description : ajoute toutes les fonctions à la table des symboles.

*/

void fillSymTableWithVariable(FCTSYM fct, TREE tree, int level, char *type);
/*

	a. Objets utilisés:
		i. FCTSYM fct: la fonction dans laquelle sont déclarées les variables à ajouter.
		ii.TREE tree : le nœud de l’arbre correspondant à la fonction.
		iii.Int level : le niveau de la variable (égal au niveau de la fonction qui la contient).
		iv.Char *type : le type de la variable.

	b. Pré-conditions : la fonction se trouve dans la table des symboles.
	c. Post-conditions : les variables de la fonction ont toutes été ajoutées dans la table des symboles.
	d. Description : ajoute l’ensemble des variables déclarées dans la fonction dans la table des symboles.
*/


void fillSymTableWithArgument(FCTSYM fct, TREE tree, int level, char *type, int varMode);
/*

	a. Objets utilisés:
		i. FCTSYM fct: la fonction qui possède les arguments à ajouter.
		ii.TREE tree : le nœud de l’arbre correspondant à la fonction.
		iii.Int level : le niveau de la variable (égal au niveau de la fonction qui la contient).
		iv.Char *type : le type de la variable.
		v.Int varMode : la mode de passage en paramètre de l’argument.
	b. Pré-conditions : la fonction se trouve dans la table des symboles.
	c. Post-conditions : les arguments de la fonction (s’il y en a) ont tous été ajoutés à la table des symboles.
	d. Description : ajoute les arguments de la fonction à la table des symboles.

*/

extern FCTSYM addFctToSymTable(FCTSYM parentFct, TREE locationOnTree,char* name,char* retType, int isMain, int level);
/*
	a. Objets utilisés:
		i. FCTSYM parentFct: la fonction dans laquelle est imbriquée la fonction à ajouter.
		ii.TREE locationOnTree : le nœud de l’arbre correspondant à la fonction.
		iii.Char *name : le nom de la fonction.
		iv.Char *retType : le type de retour de la fonction.	
		v.Int isMain : entier qui prend la valeur 1 si la fonction est la fonction main, 0 sinon.
		vi.Int level : le niveau d’imbrication de la fonction (-1 pour la fonction racine qui est une fonction fictive dans laquelle les fonctions de niveau 0 sont 					imbriquées).
	b. Pré-conditions : la table des symboles a ete creee.
	c. Post-conditions : un noeud de type FCTSYM a été ajouté à la table des symboles.
	d. Description : ajoute un noeud de type fonction (FCTSYM) à la table des symboles.
*/

extern VARSYM addVarToSymTable(FCTSYM fct, TREE locationOnTree,char* name, char* type, int level, int varMode);
/*
	a. Objets utilisés:
		i. FCTSYM fct: la function dans laquelle est declare la variable à ajouter.
		ii.TREE locationOnTree : le noeud de l’arbre correspondant à la variable.
		iii.Char *name : le nom de la variable.
		iv.Char *type : le type de la variable.
		v.Int level : le niveau de la variable (égal au niveau de la fonction qui la
				contient).
		vi.Int varMode : le mode de passage en paramètres : -1 si c’est une variable de la fonction, 0 si c’est un argument passé par valeur et 1 si c’est un
				 argument passé par référence.

	b. Pré-conditions : la fonction dans laquelle se trouve la variable est dans la table des symboles.
	c. Post-conditions : un noeud de type VARSYM a été ajouté à la table des symboles.
	d. Description : ajoute un noeud de type variable (VARSYM) à la table des symboles.

*/


extern FCTSYM searchFctAtParentFct(FCTSYM fct, char *name);
/*
	a. Objets utilisés:
		i. FCTSYM fct: la fonction parente, dans laquelle est imbriquée la fonction recherchée.
		ii.Char *name : le nom de la fonction recherchée.
	b. Pré-conditions : une table des symboles existe et la fonction parente y est présente.
	c. Post-conditions : retourne la fonction si elle a été trouvée, NULL sinon.
	d. Description : recherche une fonction imbriquée dans une autre.
*/

extern VARSYM searchVarAtFct(FCTSYM fct, char *name);
/*
	a. Objets utilisés:
		i. FCTSYM fct: la fonction dans laquelle on cherche la variable.
		ii.Char *name : le nom de la variable recherchée.
	b. Pré-conditions : une table des symboles existe, la fonction en fait partie.
	c. Post-conditions : retourne la variable si elle a été trouvée, NULL sinon.
	d. Description : recherche une variable dans une fonction.
*/

extern VARSYM searchVarAtFctByPos(FCTSYM fct, int pos);
/*
	a. Objets utilisés:
		i. FCTSYM fct: la fonction dans laquelle on cherche la variable.
		ii.Int pos : la position de la variable recherchée.
	b. Pré-conditions : une table des symboles existe.
	c. Post-conditions : retourne la variable si elle a été trouvée, NULL sinon.
	d. Description : recherche une variable dans une fonction.
*/

extern int alreadyIsSymbolFctInParentFct(FCTSYM symFct, char* name);
/*
	a. Objets utilisés:
		i. FCTSYM symFct: la fonction dans laquelle est imbriquée la fonction à ajouter.
		ii.Char *name : le nom de la fonction à ajouter.
	b. Pré-conditions : la fonction parente existe (éventuellement la racine si la fonction à ajouter est de niveau 0).
	c. Post-conditions : retourne 1 si une fonction du même nom existe parmi les fonctions filles de la fonction passée en paramètre, 0 sinon.
	d. Description : vérifie si une fonction du même nom a déjà été ajoutée dans la table des symboles parmi les fonctions filles de la fonction parente.
*/

extern int alreadyIsSymbolVar(FCTSYM symFct, char* name);
/*
	a. Objets utilisés:
		i. FCTSYM symFct: la fonction dans laquelle est déclarée la variable ou qui contient l’argument s’il s’agit d’un ajout d’argument.
		ii.Char *name : le nom de la variable.
	b. Pré-conditions : la fonction existe.
	c. Post-conditions : retourne 1 si une variable ou un argument du même nom existe parmi les variables déjà ajoutées 
			     dans la liste des variables de la fonction, 0 sinon.
	d. Description : vérifie si une variable du même nom a déjà été ajoutée dans la liste des variables de la fonction.

*/

void printSymbolVar(VARSYM varSym);

/*
	a. Objets utilisés :
		i. VARSYM varSym : la variable à afficher.
	b. Pré-conditions : /.
	c. Post-conditions : les variables d’une fonction ont été affichées à l’écran.
	d. Description : affiche la liste des variables d’une fonction à l’écran.
*/

extern void printSymbolTable(FCTSYM symFct);
/*
	a. Objets utilisés :
		i. FCTSYM symFct : la fonction à afficher.
	b. Pré-conditions : /.
	c. Post-conditions : la table des symboles à été affichée à l’écran.
	d. Description : affiche la table des symboles à l’écran.
*/

extern int alreadyIsSymbolVar(FCTSYM symFct, char *name);
/*
	a. Objets utilisés:
		i. FCTSYM symFct: la fonction dans laquelle est déclarée la variable ou qui contient l’argument s’il s’agit d’un ajout d’argument.
		ii.Char *name : le nom de la variable.
	b. Pré-conditions : la fonction existe.
	c. Post-conditions : retourne 1 si une variable ou un argument du même nom existe parmi les variables déjà ajoutées dans la liste des variables de la fonction, 0 				     sinon.
	d. Description : vérifie si une variable du même nom a déjà été ajoutée dans la liste des variables de la fonction.
*/

extern int alreadyIsSymbolFctInParentFct(FCTSYM symFct, char *name);
/*
	a. Objets utilisés:
		i. FCTSYM symFct: la fonction dans laquelle est imbriquée la fonction à ajourer.
		ii.Char *name : le nom de la fonction à ajouter.
	b. Pré-conditions : la fonction parente existe (éventuellement la racine si la fonction à ajouter est de niveau 0).
	c. Post-conditions : retourne 1 si une fonction du même nom existe parmi les fonctions filles de la fonction passée en paramètre, 0 sinon.
	d. Description : vérifie si une fonction du même nom a déjà été ajoutée dans la table des symboles parmi les fonctions filles de la fonction parente.
*/

extern void printSymTableForDia(FCTSYM fct, int nb)
/*
	a. Objets utilisés:
		i. FCTSYM fct: la table des symboles à imprimer.
		ii.Int nb: nombre entier permettant de différencier les noeuds NULL. Évite que 				   tous les pointeurs NULL pointent vers le même endroit.
	b. Pré-conditions : /.
	c. Post-conditions : la table des symboles a été imprimée sous forme de graphe.
	d. Description : imprime la table des symboles sous forme d'arbre.
*/

void printVariable(VARSYM v, int nb)
/*
	a. Objets utilisés:
		i. VARSYM v: la variable à imprimer.
		ii.Int nb: nombre entier permettant de différencier les noeuds NULL. Évite que 				   tous les pointeurs NULL pointent vers le même endroit.
	b. Pré-conditions : /.
	c. Post-conditions : variable a été imprimée et pourra être ajoutée au graphe.
	d. Description : imprime la variable pour pouvoir l'ajouter au graphe de la table des 				 symboles.
*/

#endif


